﻿NAMFox.ns(function() { with (NAMFox) {

name("AJAX Tests");

//////////////////////////////////////////////
// Helpers
//////////////////////////////////////////////

var consoleService = $("@mozilla.org/consoleservice;1").service("nsIConsoleService");

//////////////////////////////////////////////
// Test Cases
//////////////////////////////////////////////

test("AJAX request with no URL throws", function() {
    expectError(function() { $.get(null); }, "NS_ERROR_FAILURE", "You may not get data from or post to a URL which is null or empty.");
});

asyncTest("$.get does HTTP GET request", function() {
    $.get(
        "http://positionabsolute.net/projects/javascript/AjaxTimeout/responder.php",
        null,
        function (xhr) {
            equals("..finally", xhr.responseText, "The response text must be '..finally'.");
            start();
        }
    );
});

asyncTest("$.get parses data into query string", function() {
    $.get(
        "http://www.neoseeker.com/forums/115/",
        {
            keywords: "foo"
        },
        function (xhr) {
            ok(xhr.responseText.indexOf("?keywords=foo") !== -1, "The response text must contain the query string.", "$get_parsesDataIntoQueryString");
            start();
        }
    );
});

asyncTest("$.get with invalid URL returns 404", function() {
    $.get(
        "http://www.neoseeker.com/members/horrible/winsternitz/creedthoughts",
        null,
        function (xhr) {
            equals(400, xhr.status, "Failure");
            equals("lol", xhr.responseText, "failure");
            ok(false, "The request should not be successful.");
            start();
        },
        function (xhr, causedByTimeout) {
            equals(404, xhr.status, "The failure should be a 404 error.");
            ok(!causedByTimeout, "The failure should not be caused by timeout.");
            start();
        }
    );
});

asyncTest("Error thrown from callback is logged", function() {
    consoleService.reset();
    
    $.get(
        "http://www.google.com",
        null,
        function (xhr) {
            try {
                throw new Error("Catch me if you can.");
            }
            finally {
                setTimeout(verify, 20);
            }
        },
        null
    );
    
    function verify() {
        var messages = {};
        var messageCount = {};
        consoleService.getMessageArray(messages, messageCount);
        ok(messageCount.value > 1, "There should be an error logged.");
        
        var foundError = false;
        for (var i = 0; i < messageCount.value; ++i) {
            foundError = messages.value[i].message.indexOf("Catch me if you can.") !== -1;
            
            if (foundError) {
                break;
            }
        }
        
        ok(foundError, "The exception message 'Catch me if you can.' should appear in the message log.");
        
        start();
    }
});

asyncTest("Bypassing cache gets fresh data", function() {
    var asyncCompletionCount = 0;
    var observerService = $("@mozilla.org/observer-service;1").service("nsIObserverService");
    var cacheObserver = {
        observe: function(subject, topic, data) {
            var channel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
            channel.setResponseHeader("cache-control", "max-age=9500", false);
        }
    };
    
    var word;
    try {
        observerService.addObserver(cacheObserver, "http-on-examine-response", false);
        
        var LoadFlags = Components.interfaces.nsIRequest;
        var xhr = $("@mozilla.org/xmlextras/xmlhttprequest;1").instance("nsIXMLHttpRequest");
        
        xhr.open("GET", "http://watchout4snakes.com/creativitytools/RandomWord/RandomWordPlus.aspx", true);
        
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                var results = xhr.responseText.match(/<span id="tmpl_main_lblWord" class="randomWord">(.*?)<\/span>/);
                if (results) {
                    word = results[1];
                }
                
                xhr = $("@mozilla.org/xmlextras/xmlhttprequest;1").instance("nsIXMLHttpRequest");
                xhr.open("GET", "http://watchout4snakes.com/creativitytools/RandomWord/RandomWordPlus.aspx", true);
                xhr.channel.loadFlags = LoadFlags.LOAD_FROM_CACHE | LoadFlags.VALIDATE_NEVER;
                
                xhr.onreadystatechange = function() {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        results = xhr.responseText.match(/<span id="tmpl_main_lblWord" class="randomWord">(.*?)<\/span>/);
                        if (results) {
                            var secondWord = results[1];
                            equals(word, secondWord, "The words should be the same when using raw XHRs.");
                            signal();
                            setTimeout(validateWithCacheApi, 500);
                        }
                    }
                }
                
                xhr.send(null);
            }
        }
        
        xhr.send(null);
    }
    finally {
        observerService.removeObserver(cacheObserver, "http-on-examine-response");
    }
    
    function validateWithCacheApi() {
        $.get(
            "http://watchout4snakes.com/creativitytools/RandomWord/RandomWordPlus.aspx",
            null,
            function (xhr2) {
                var newWord = xhr2.responseText.match(/<span id="tmpl_main_lblWord" class="randomWord">(.*?)<\/span>/)[1];
                equals(word, newWord, "The words should be the same when using $.cacheHandling.useCache.");
                signal();
            },
            null,
            $.cacheHandling.useCache
        );
        
        $.get(
            "http://watchout4snakes.com/creativitytools/RandomWord/RandomWordPlus.aspx",
            null,
            function (xhr2) {
                var newWord = xhr2.responseText.match(/<span id="tmpl_main_lblWord" class="randomWord">(.*?)<\/span>/)[1];
                notEqual(word, newWord, "The original word (" + word + ") should not match the new word (" + newWord + ") when using $.cacheHandling.bypassCache");
                signal();
            },
            null,
            $.cacheHandling.bypassCache
        );
    }
    
    function signal() {
        if (++asyncCompletionCount === 3) {
            start();
        }
    }
});

asyncTest("$.post sends data in HTTP request body", function() {
    $.post(
        "http://wwwx.cs.unc.edu/~jbs/aw-wwwp/docs/resources/perl/perl-cgi/programs/cgi_stdin.cgi",
        {
            name: "My Name",
            textarea: "Comments",
            radiobutton: "radio",
            checkedbox: "whipped cream",
            selectitem: "watercress"
        },
        function (xhr) {
            ok(xhr.responseText.indexOf("name = My Name") !== -1, "The name variable should be posted with the value 'My Name'.");
            ok(xhr.responseText.indexOf("textarea = Comments") !== -1, "The textarea variable should be posted with the value 'Comments'.");
            ok(xhr.responseText.indexOf("radiobutton = radio") !== -1, "The radiobutton variable should be posted with the value 'radio'.");
            ok(xhr.responseText.indexOf("checkedbox = whipped cream") !== -1, "The checkedbox variable should be posted with the value 'whipped cream'.");
            ok(xhr.responseText.indexOf("selectitem = watercress") !== -1, "The selectitem variable should be posted with the value 'watercress'.");
            start();
        }
    );
});

asyncTest("$.get is aborted at 20 seconds", function() {
    $.get(
        "http://positionabsolute.net/projects/javascript/AjaxTimeout/responder.php",
        {
            delay: 30
        },
        function (xhr) {
            ok(false, "The request should not be successful.");
            start();
        },
        function (xhr, causedByTimeout) {
            ok(causedByTimeout, "The failure should be caused by timeout.");
            start();
        },
        $.cacheHandling.bypassCache
    );
});

}});